﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using EntityFrameworkContrib.PostSharp4EF;

namespace EFContrib.PS4EF.Tst.ComplexType
{
    /// <summary>
    /// Summary description for ComplexTypeTest
    /// </summary>
    [TestClass]
    public class ComplexTypeTest
    {
        #region setup
        public ComplexTypeTest()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion 
        #endregion

        [TestInitialize()]
        public void MyTestInitialize()
        {
            using (ComplexTypesTestEntities context = new ComplexTypesTestEntities())
            {
                // clear out database
                foreach (Person old in context.Person)
                {
                    context.DeleteObject(old);
                }

                context.SaveChanges();
            }
        }

        /// <summary>
        /// Tests that the changetracker is correctly attached/removed to complextypes
        /// </summary>
        [TestMethod]
        public void testComplexTypeChangeTrackerInjection()
        {
            using (ComplexTypesTestEntities context = new ComplexTypesTestEntities())
            {
                Person p = new Person { FirstName = "Ruurd", LastName = "Boeke" };

                // attaching will set the changetracker
                context.AddToPerson(p);

                Address a = new Address { City = "Rotterdam", Street = "My Street", PostalCode = "1111 VA" };
                NestedComplexType n = new NestedComplexType { A = 1, B = 2 };
                a.NestedComplexType = n;
                p.Address = a;

                IGetChangeTracker ctA = PostSharp.Post.Cast<Address, IGetChangeTracker>(a);
                Assert.IsNotNull(ctA.GetChangeTracker());

                Address b = new Address { City = "Redmond", Street = "Your street", PostalCode = "2222 BB" };
                b.NestedComplexType = n;
                p.Address = b;
                b.NestedComplexType.A = 3;
                Assert.IsNull(ctA.GetChangeTracker());

                IGetChangeTracker ctB = PostSharp.Post.Cast<Address, IGetChangeTracker>(b);
                Assert.IsNotNull(ctB.GetChangeTracker());

                context.SaveChanges();
            }

            // test endresult
            using (ComplexTypesTestEntities context = new ComplexTypesTestEntities())
            {
                Person p = context.Person.First();

                Assert.IsTrue(p.Address.City == "Redmond"); // the adress was changed

                Assert.IsTrue(p.Address.NestedComplexType.A == 3); // nested complextype was also changed.
                Assert.IsTrue(p.Address.NestedComplexType.B == 2);
            }
        }
    }


}
